#include "renderer.h"
#include <QtOpenGL>

Renderer::Renderer()
{
}

void Renderer::applyColor(const QColor &color)
{
    glColor4f(color.red()/255.0f, color.green()/255.0f, color.blue()/255.0f, color.alpha()/255.0f);
}

void Renderer::drawLine(const QPointF &start, const QPointF &end, const QColor &color, float lineWidth, LineStyle* pStyle)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    applyColor(color);
    glLineWidth(lineWidth);

    if(pStyle)
    {
        glEnable(GL_LINE_STIPPLE);
        glLineStipple(pStyle->factor, pStyle->pattern);
    }

    glBegin(GL_LINES);

    glVertex2f(start.x(), start.y());
    glVertex2f(end.x(), end.y());

    glEnd();

    glPopAttrib();
}

void Renderer::drawRect(const QRectF &rect, const QColor &color, float lineWidth, Renderer::LineStyle *pStyle)
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    applyColor(color);
    glLineWidth(lineWidth);
    if(pStyle)
    {
        glEnable(GL_LINE_STIPPLE);
        glLineStipple(pStyle->factor, pStyle->pattern);
    }

    glBegin(GL_LINE_LOOP);

    glVertex2f(rect.topLeft().x(), rect.topLeft().y());
    glVertex2f(rect.topRight().x(), rect.topRight().y());
    glVertex2f(rect.bottomRight().x(), rect.bottomRight().y());
    glVertex2f(rect.bottomLeft().x(), rect.bottomLeft().y());

    glEnd();

    glPopAttrib();
}

void Renderer::drawCircle(const QPointF &center, float radius, const QColor &color, float lineWidth, Renderer::LineStyle *pStyle)
{
    float fullCircle = 2*3.14159265f;
    float angInc = fullCircle/360;

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushMatrix();
    glTranslatef(center.x(), center.y(), 0.0f);

    applyColor(color);
    glLineWidth(lineWidth);
    if(pStyle)
    {
        glEnable(GL_LINE_STIPPLE);
        glLineStipple(pStyle->factor, pStyle->pattern);
    }

    glBegin(GL_LINES);

    float ang1 = 0;
    float ang2 = 0;

    for(int i=0;i < 360; i++)
    {
        ang1 = i*angInc;
        ang2 = (i + 1)*angInc;

        float x1 = radius*cos(ang1);
        float y1 = radius*sin(ang1);

        float x2 = radius*cos(ang2);
        float y2 = radius*sin(ang2);

        glVertex2f(x1, y1);
        glVertex2f(x2, y2);
    }

    glEnd();

    glPopMatrix();
    glPopAttrib();
}

void Renderer::drawCircle(const QPointF &center, float radius, float startAngle, float endAngle,
                          const QColor &color, float lineWidth, Renderer::LineStyle *pStyle)
{
    float partialCircle = endAngle - startAngle;
    float angInc = partialCircle/360;

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glPushMatrix();
    glTranslatef(center.x(), center.y(), 0.0f);

    applyColor(color);
    glLineWidth(lineWidth);
    if(pStyle)
    {
        glEnable(GL_LINE_STIPPLE);
        glLineStipple(pStyle->factor, pStyle->pattern);
    }

    glBegin(GL_LINES);

    float ang1 = 0;
    float ang2 = 0;

    for(int i=0;i < 360; i++)
    {
        ang1 = i*angInc;
        ang2 = (i + 1)*angInc;

        float x1 = radius*cos(ang1);
        float y1 = radius*sin(ang1);

        float x2 = radius*cos(ang2);
        float y2 = radius*sin(ang2);

        glVertex2f(x1, y1);
        glVertex2f(x2, y2);
    }

    glEnd();

    glPopMatrix();
    glPopAttrib();
}

void Renderer::enableBlending(Renderer::BlendMode mode)
{
    glEnable(GL_BLEND);

    if(mode == AlphaOpacity)
    {
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }
}

void Renderer::disableBlending()
{
    glDisable(GL_BLEND);
}
